/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bittorentlike;

import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import define.Define;

/**
 *
 * @author Xuan Cau
 */
public class ThreadDowload extends Thread
{
    private ThreadChunk[] _thread_chunk;
    private byte[][] _torrent;
    private byte[][] _data_recieve;
    private int _num_finished;
    
    private String _file_name;
    private String _host_name;
    private MainControl _main;
    private File _file_down;
    private FileOutputStream _fop = null;
    private DownloadFile _frm_download;
    public ThreadDowload(MainControl main,String file_name,String host_name)
    {
        _main = main;
        // thong tin file can down,torrent.
        _file_name = file_name;
        _host_name = host_name;
        
        _num_finished = 0;
        
        _frm_download = new DownloadFile();
        _frm_download.SetControl(this);
        _frm_download.setVisible(true);
        _frm_download.setTitle("Download " + _file_name);
        _frm_download.SetFileName(file_name);
        _frm_download.SetSaveTo("download");
        
        _file_down = new File("download\\" + _file_name);
        try
        {
            _fop = new FileOutputStream(_file_down);
        }
        catch(Exception ex)
        {
            
        }
    }
    public void run()
    {
       
    }
    public void Pause()
    {
        for(int i = 0;i<_thread_chunk.length;i++)
        {
            _thread_chunk[i].Pause();
        }
    }
    public void Stop()
    {
        for(int i = 0;i<_thread_chunk.length;i++)
        {
            _thread_chunk[i].stop();
        }
    }
    public void NewChunk(byte[] chunk,int id)
    {
        if(_data_recieve[id] == null)
        {
           _data_recieve[id] = chunk;
           float c = GetCurrent();
           _frm_download.setValueProgressBar((int)(c*100));
           _num_finished += 1;
           
           float size  = (float)(_num_finished * Define.MAX_CHUNK)/(1024*1024);
           _frm_download.SetCurrent(size);
        }
        if(_num_finished == _torrent.length)
        {
            for(int i = 0;i<_data_recieve.length;i++)
            {
                try
                {        
                   _fop.write(_data_recieve[i]);
                }
                catch(Exception ex)
                {
                   System.out.println("" + ex.getMessage());
                }
            }
            try
            {
               _fop.close();
            }
            catch(Exception ex)
            {

            }
            // dong cua so download lai.
            _frm_download.setVisible(false);
        }
    }
    public int GetIdChunk()
    {
        for(int i = 0;i<_data_recieve.length;i++)
        {
            if(_data_recieve[i] == null)
                return i;
        }
        return -1;
    }
    public byte[] GetTorrent(int id)
    {
        return _torrent[id];
    }
    public void SetFile(byte[][] torrent)
    {
        this._torrent = torrent;
        float size  = (float)(_torrent.length * Define.MAX_CHUNK)/(1024*1024);
        _frm_download.SetSize(size);
        this._data_recieve = new byte[torrent.length][];
        if(torrent.length <= Define.NUM_THREAD_IN_DOWNLOAD)
        {
            _thread_chunk = new ThreadChunk[torrent.length];
            for(int i = 0;i<torrent.length;i++)
            {
               _thread_chunk[i] =  new ThreadChunk(this,_torrent[i],i);
               _thread_chunk[i].start();
            }
        }
        else
        {
            _thread_chunk = new ThreadChunk[define.Define.NUM_THREAD_IN_DOWNLOAD];
            for(int i = 0;i<define.Define.NUM_THREAD_IN_DOWNLOAD;i++)
            {
               _thread_chunk[i] = new ThreadChunk(this,_torrent[i],i);
               _thread_chunk[i].start();
            }
        }
    }
    public void SetSpeed(float speed)
    {
        _frm_download.SetSpeed(speed);
    }
    public byte[] GetChunk(byte[] data)
    {
       return _main.GetChunk(data);
    }
    public float GetCurrent()
    {
        int result = 0;
        for(int i =0;i<_data_recieve.length;i++)
        {
            if(_data_recieve[i]!=null)
                result ++;
        }
        return (float)result/_data_recieve.length;
    }
}
